//
// Copyright (C) 2020-2021 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0

package requests

import (
	"encoding/json"
	"github.com/edgexfoundry/edgex-go/internal/app/dtos"
	"github.com/edgexfoundry/edgex-go/internal/app/models"
	"github.com/edgexfoundry/go-mod-core-contracts/v2/common"
	_ "github.com/edgexfoundry/go-mod-core-contracts/v2/models"

	dtoCommon "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common"
	"github.com/edgexfoundry/go-mod-core-contracts/v2/errors"
)

// AddProductCategoryRequest defines the Request Content for POST ProductCategory DTO.
// This object and its properties correspond to the AddProductCategoryRequest object in the APIv2 specification:

type AddProductCategoryRequest struct {
	dtoCommon.BaseRequest `json:",inline"`
	ProductCategory       dtos.ProductCategory `json:"productCategory"`
}

// Validate satisfies the Validator interface
func (d AddProductCategoryRequest) Validate() error {
	err := common.Validate(d)
	return err
}

/**
 * @Description 用来数据转换
 * @method
 * @auth kely
 * @Date 2023-2-22
 * @Param
 * @return
 **/

// UnmarshalJSON implements the Unmarshaler interface for the AddDeviceRequest type
func (d *AddProductCategoryRequest) UnmarshalJSON(b []byte) error {
	var alias struct {
		dtoCommon.BaseRequest
		ProductCategory dtos.ProductCategory `json:"productCategory"` // 对传输过来的数据，获取数据中的productCategory 转为对象
	}
	if err := json.Unmarshal(b, &alias); err != nil {
		return errors.NewCommonEdgeX(errors.KindContractInvalid, "Failed to unmarshal request body as JSON.", err)
	}

	*d = AddProductCategoryRequest(alias)

	// 去掉中文校验
	// validate AddDeviceRequest DTO
	//if err := d.Validate(); err != nil {
	//	return err
	//}
	return nil
}

// AddProductCategoryReqToDeviceModels transforms the AddProductCategoryReqToDeviceModels DTO array to the ProductCategory model array
func AddProductCategoryReqToDeviceModels(addRequests []AddProductCategoryRequest) (ProductCategory []models.ProductCategory) {
	for _, req := range addRequests {
		d := dtos.ToProductCategoryModel(req.ProductCategory)
		ProductCategory = append(ProductCategory, d)
	}
	return ProductCategory
}

// UpdateDeviceRequest defines the Request Content for PUT event as pushed DTO.
// This object and its properties correspond to the UpdateDeviceRequest object in the APIv2 specification:
// https://app.swaggerhub.com/apis-docs/EdgeXFoundry1/core-metadata/2.1.0#/UpdateDeviceRequest
type UpdateproductCategoryRequest struct {
	dtoCommon.BaseRequest `json:",inline"`
	ProductCategory       dtos.UpdateProductCategory `json:"productCategory"`
}

// Validate satisfies the Validator interface
func (d UpdateproductCategoryRequest) Validate() error {
	err := common.Validate(d)
	return err
}

// UnmarshalJSON implements the Unmarshaler interface for the UpdateDeviceRequest type
func (d *UpdateproductCategoryRequest) UnmarshalJSON(b []byte) error {
	var alias struct {
		dtoCommon.BaseRequest
		ProductCategory dtos.UpdateProductCategory
	}
	if err := json.Unmarshal(b, &alias); err != nil {
		return errors.NewCommonEdgeX(errors.KindContractInvalid, "Failed to unmarshal request body as JSON.", err)
	}

	*d = UpdateproductCategoryRequest(alias)

	// validate UpdateDeviceRequest DTO
	if err := d.Validate(); err != nil {
		return err
	}
	return nil
}

// ReplaceDeviceModelFieldsWithDTO replace existing Device's fields with DTO patch
func ReplaceDeviceModelFieldsWithDTO(productCategory *models.ProductCategory, patch dtos.UpdateProductCategory) {
	if patch.Description != nil {
		productCategory.Description = *patch.Description
	}
	if patch.Name != nil {
		productCategory.Name = *patch.Name
	}
	if patch.Order != nil {
		productCategory.Order = *patch.Order
	}
}

func NewAddDeviceRequest(dto dtos.ProductCategory) AddProductCategoryRequest {
	return AddProductCategoryRequest{
		BaseRequest:     dtoCommon.NewBaseRequest(),
		ProductCategory: dto,
	}
}

func NewUpdateDeviceRequest(dto dtos.UpdateProductCategory) UpdateproductCategoryRequest {
	return UpdateproductCategoryRequest{
		BaseRequest:     dtoCommon.NewBaseRequest(),
		ProductCategory: dto,
	}
}
